package app.r_teenus.backend.dao;

import java.util.ArrayList;
import java.util.List;

import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Restrictions;
import org.springframework.security.GrantedAuthority;
import org.springframework.security.context.SecurityContextHolder;
import org.springframework.security.userdetails.UserDetails;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

import app.r_teenus.backend.model.Customer;
import app.r_teenus.backend.model.Enterprise;
import app.r_teenus.backend.model.Person;
import app.r_teenus.backend.model.ServiceOrder;
import app.r_teenus.backend.model.ServiceRequest;
import app.r_teenus.backend.model.ServiceRequestStatusType;
import app.r_teenus.backend.model.UserAccount;


@Repository("requestDao")
@Transactional(readOnly = true)
public class ServiceRequestDaoImpl extends DefaultDaoImpl implements ServiceRequestDao {

	
	public List<ServiceRequest> findServiceRequests() {
		List<ServiceRequest> list = new ArrayList<ServiceRequest>();
		Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
		if (principal instanceof UserDetails) {

			String userName = ((UserDetails) principal).getUsername();
			String userPassword = ((UserDetails) principal).getPassword();
			GrantedAuthority[] roles =((UserDetails) principal).getAuthorities();
			if ( roles.length == 1 && roles[0].toString().equals("ROLE_CLIENT")){
				
				DetachedCriteria criteria = DetachedCriteria.forClass(UserAccount.class);
				criteria.add(Restrictions.eq("name", userName));
				
				List<UserAccount> userAccount = hibernateTemplate.findByExample(new UserAccount(userName, userPassword));
				Customer cus = hibernateTemplate.get(Customer.class, userAccount.get(0).getSubject());
				criteria = DetachedCriteria.forClass(ServiceRequest.class);
				criteria.add(Restrictions.eq("customer", cus));
				list = hibernateTemplate.findByCriteria(criteria);
				
			}else if ( roles.length == 3){
				list = hibernateTemplate.loadAll(ServiceRequest.class);

			}
			for (ServiceRequest ser : list) {
				getCustomer(ser);
				DetachedCriteria criteria = DetachedCriteria.forClass(ServiceOrder.class);
				criteria.createAlias("serviceRequest", "serviceRequest");
				criteria.add(Restrictions.disjunction().add(Restrictions.eq("serviceRequest", ser)));
				if (hibernateTemplate.findByCriteria(criteria).isEmpty()) {
					ser.setCanRemove(true);
				}
			}
		}
		return list;
	}
	
	
	public ServiceRequest addRequest() {
		Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
		ServiceRequest serviceRequest = new ServiceRequest();
		serviceRequest.setId(0);
		if (principal instanceof UserDetails) {

			String userName = ((UserDetails) principal).getUsername();
			String userPassword = ((UserDetails) principal).getPassword();
			GrantedAuthority[] roles = ((UserDetails) principal).getAuthorities();
			if (roles.length == 1 && roles[0].toString().equals("ROLE_CLIENT")) {

				DetachedCriteria criteria = DetachedCriteria.forClass(UserAccount.class);
				criteria.add(Restrictions.eq("name", userName));

				List<UserAccount> userAccount = hibernateTemplate.findByExample(new UserAccount(userName, userPassword));
				Customer cus = hibernateTemplate.get(Customer.class, userAccount.get(0).getSubject());
				serviceRequest.setCustomer(cus);
				getCustomer(serviceRequest);
				serviceRequest.setSearchText(userName);
			}
		}
		
		return serviceRequest;
	}

	public void getCustomer(ServiceRequest ser) {
		if (ser.getCustomer().getSubject_type() == 1) {
			ser.getCustomer().setPerson(hibernateTemplate.get(Person.class, ser.getCustomer().getSubject()));
		} else if (ser.getCustomer().getSubject_type() == 2) {
			ser.getCustomer().setEnterprise(hibernateTemplate.get(Enterprise.class, ser.getCustomer().getSubject()));
		}
	}

	
	public ServiceRequest findRequestById(Integer id) {
		ServiceRequest serviceRequest = hibernateTemplate.get(ServiceRequest.class, id);
		getCustomer(serviceRequest);
		serviceRequest.setSearchText("");
		DetachedCriteria criteria = DetachedCriteria.forClass(ServiceOrder.class);
		criteria.createAlias("serviceRequest", "serviceRequest");
		criteria.add(Restrictions.disjunction().add(Restrictions.eq("serviceRequest", serviceRequest)));
		if (!hibernateTemplate.findByCriteria(criteria).isEmpty()) {
			serviceRequest.setExistOrder(true);
		}
		return serviceRequest;
	}

	
	@Transactional(readOnly = false)
	public void deleteRequest(Integer id) {
		ServiceRequest ser = hibernateTemplate.get(ServiceRequest.class, id);
		hibernateTemplate.delete(ser);
	}

	
	public ServiceRequest createNewRequest() {
		ServiceRequest serviceRequest = new ServiceRequest();
		serviceRequest.setId(-1);
		serviceRequest.setList(findServiceRequests());
		return serviceRequest;
	}

	
	@Transactional(readOnly = false)
	public ServiceRequest save(ServiceRequest serviceRequest) {
		if (serviceRequest.getServiceRequestStatusType() == null) {
			ServiceRequestStatusType type = new ServiceRequestStatusType();
			type.setId(1);// registreeritud
			serviceRequest.setServiceRequestStatusType(type);
			serviceRequest.setId(null);
		}
		hibernateTemplate.saveOrUpdate(serviceRequest);
		return serviceRequest;
	}

	
	public ServiceRequest findCustomer(ServiceRequest serviceRequest) {
		String personQuery = "SELECT * FROM PERSON  INNER JOIN CUSTOMER ON customer.subject_fk=person.person and customer.SUBJECT_TYPE_FK = 1 ";
		personQuery = personQuery + " and person.first_name = " + "\'" + serviceRequest.getSearchText() + "\'";
		String enterpriseQuery = "SELECT * FROM ENTERPRISE  INNER JOIN CUSTOMER ON customer.subject_fk=enterprise.enterprise and customer.SUBJECT_TYPE_FK = 2 ";
		enterpriseQuery = enterpriseQuery + " and enterprise.name like " + "\'%" + serviceRequest.getSearchText() + "%\'";
		List<Person> persons = hibernateTemplate.getSessionFactory().getCurrentSession().createSQLQuery(personQuery).addEntity("person", Person.class).list();//
		if (!persons.isEmpty()) {
			Customer customer = new Customer();
			customer.setSubject_type(1);
			Person person = persons.get(0);
			customer.setSubject(person.getId());
			List<Customer> customers = hibernateTemplate.findByExample(customer);
			if (!customers.isEmpty()) {
				customer = customers.get(0);
				customer.setPerson(person);
				serviceRequest.setCustomer(customer);
			}
		} else {
			List<Enterprise> enterprises = hibernateTemplate.getSessionFactory().getCurrentSession().createSQLQuery(enterpriseQuery).addEntity("enterprise", Enterprise.class).list();
			if (!enterprises.isEmpty()) {
				Customer customer = new Customer();
				customer.setSubject_type(2);
				Enterprise enterprise = enterprises.get(0);
				customer.setSubject(enterprise.getId());
				List<Customer> customers = hibernateTemplate.findByExample(customer);
				if (!customers.isEmpty()) {
					customer = customers.get(0);
					customer.setEnterprise(enterprise);
					serviceRequest.setCustomer(customer);
				}
			} else {
				serviceRequest.setSearchText(null);
			}

		}

		return serviceRequest;
	}
}
